home *** CD-ROM | disk | FTP | other *** search
- /* Copyright, 1990, Regents of the University of Colorado */
- /* This program does a matrix-matrix multiply, of two matrices of size
- * N x N, where N is a multiple of P, the number of environments.
- *
- * The basic algorithm is to block the first matrix
- * by rows and send a block to each processor, and
- * block the second matrix by columns and send a block
- * to each processor. Each processor computes the
- * results for that sub-matrix for which it has data
- * and then the blocks of columns are all shifted to
- * the right one processor. */
-
- #include "dino.h"
-
- #define N 32
- #define P 16
-
- environment node[P:id] {
-
- composite mult (in A, in B, out C)
- float distributed A[N][N] map BlockRow; /* First matrix */
- float distributed B[N][N] map BlockCol; /* Second matrix */
- float distributed C[N][N] map BlockRow; /* Result matrix */
-
- {
- int i, j, k, l; /* Looping variables */
- int my_first, my_last; /* Columns of B which are mine */
- int left_first, left_last; /* Columns of B which are my left neighbor's */
- int left, right; /* Environment indices of my neighbors */
-
- /* Compute the environment indices of the nodes on the right and left */
- right = (id == P - 1) ? (0) : (id + 1);
- left = (id == 0) ? (P - 1) : (id - 1);
-
- /* Compute the starting and stopping indices of the data in my block */
- my_first = id * N/P;
- my_last = (id + 1) * N/P - 1;
-
- /* Compute the starting and stopping indices of the data in the block
- * of the node to the left */
- left_first = (id == 0) ? ((P - 1) * N/P) : ((id - 1) * N/P);
- left_last = (id == 0) ? (N - 1) : (id * N/P - 1);
-
- /* Loop through the blocks of columns */
- for (i = 0; i < P; i++) {
-
- /* First, send out the data that the node on the right of me will
- * need for the next iteration */
- B[][<left_first, left_last>]# {node[left]} =
- B[][<my_first, my_last>];
-
- /* Loop thru the block of C[][] that I currently have data for */
- for (j = my_first; j < my_last + 1; j++)
- for (k = 0; k < N/P; k++) {
-
- /* Compute the dot product of the appropriate data */
- C[j][k + ((id + i) * N/P) % N] = 0;
- for (l = 0; l < N; l++)
- C[j][k + ((id + i) * N/P) % N] +=
- A[j][l] * B[l][k + my_first];
- }
-
- /* Finally, receive the data from the node on the right that I need
- * for the next iteration */
- B[][<my_first, my_last>] = B[][<my_first, my_last>]# {node[right]};
- }
- }
- }
-
- environment host {
-
- main() {
-
- int i, j; /* Looping variables */
- float a[N][N], b[N][N], c[N][N];
-
- /* Initialize the two multiplicand arrays */
- printf ("Initializing...\n");
- for (i = 0; i < N; i++)
- for (j = 0; j < N; j++) {
- a[i][j] = 0.1;
- b[i][j] = (i + j) / 10.0;
- }
-
- /* Preform the computation */
- printf ("Performing the computation...\n");
- mult(a[][], b[][], c[][])#;
-
- /* Print out the results -- because the data we used for a[][] and b[][]
- * generates the same results for each row, we only print out the first
- * row */
-
- printf("Results:\n");
- for (i = 0; i < N; i++) {
- if (i % 8 == 0) printf("\n");
- printf(" %6.2f", c[0][i]);
- }
- printf("\n");
- }
- }
-